#define _GNU_SOURCE
#include <stdlib.h>
#include <cf_std.h>
#include "p7zg.h"
#include "p7zg_cui.h"
#include "p7zg_log.h"
#include "p7zip_helper.h"

enum {
    FORMAT_7Z_IDX = 0,
    FORMAT_TAR_BZ2_IDX,
    FORMAT_TAR_GZ_IDX,
    FORMAT_ZIP_IDX,
    FORMAT_COUNT
};

static const char* FormatNames[]={_("7z"),_("tar.bz2"),_("tar.gz"),_("zip")};

enum {
    LEVELS_7Z_IDX = 0,
    LEVELS_TAR_BZ2_IDX,
    LEVELS_TAR_GZ_IDX,
    LEVELS_ZIP_IDX,
    LEVELS_COUNT
};

struct xx{
    int id; 
    const char* str;
} CompLevelItems[LEVELS_COUNT][6] ={
/* 7z */
    {
        {0 , LEVEL_STR_STORE},
        {1 , LEVEL_STR_FASTEST},
        {3 , LEVEL_STR_FAST},
        {5 , LEVEL_STR_NORMAL},
        {7 , LEVEL_STR_MAXIMUM},
        {9 , LEVEL_STR_ULTRA}
    },
/* TAR_BZIP2 */
    {
        {0 , LEVEL_STR_STORE},
        {1 , LEVEL_STR_FASTEST},
        {3 , LEVEL_STR_FAST},
        {5 , LEVEL_STR_NORMAL},
        {7 , LEVEL_STR_MAXIMUM},
        {9 , LEVEL_STR_ULTRA}
    },
/* TAR_GZIP */
    {
        {0 , LEVEL_STR_STORE},
        {1 , LEVEL_STR_FASTEST},
        {3 , LEVEL_STR_FAST},
        {5 , LEVEL_STR_NORMAL},
        {7 , LEVEL_STR_MAXIMUM},
        {9 , LEVEL_STR_ULTRA}
    },
/* ZIP */
    {
        {0 , LEVEL_STR_STORE},
        {1 , LEVEL_STR_FASTEST},
        {3 , LEVEL_STR_FAST},
        {5 , LEVEL_STR_NORMAL},
        {7 , LEVEL_STR_MAXIMUM},
        {9 , LEVEL_STR_ULTRA}
    }
};

int P7zgCUiResetTo7z(P7zgCUi* this)
{
    if(gtk_combo_box_get_active((GtkComboBox*)this->formatCbt) == FORMAT_7Z_IDX){
        return 0;
    }
    gtk_combo_box_set_active((GtkComboBox*)this->formatCbt, FORMAT_7Z_IDX);
    /*
    gtk_combo_box_text_remove_all(this->levelCbt);
    for(i=0; i<sizeof(CompLevelItems[LEVELS_7Z_IDX])/sizeof(CompLevelItems[LEVELS_7Z_IDX][0]); i++)
        gtk_combo_box_text_append_text(this->levelCbt, CompLevelItems[LEVELS_7Z_IDX][i].str);
    */
    return 0;
}

int CUiResetToZip()
{
    return 0;
}

int CUiResetToTarGz()
{
    return 0;
}

int CUiResetToTarBz2()
{
    return 0;
}

static int CUiGetTarget(P7zgCUi* ui)
{
    ui->target = gtk_entry_get_text(GTK_ENTRY(ui->archiveEty));
    if(ui->target && strlen(ui->target)){
        
        return 0;
    }
    return -1;
}

static void archiveBrowsBtnOnClick(GtkWidget* widget, void* data)
{
    char* cwd;
    P7zgCUi* ui = (P7zgCUi*)data;
    GtkWidget *dialog;
    dialog = gtk_file_chooser_dialog_new ("Save File",
                          (GtkWindow*)ui->mainDlg,
                          GTK_FILE_CHOOSER_ACTION_SAVE,
                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                          GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
                          NULL);
    gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
    cwd = get_current_dir_name();
    if(cwd){
        gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), get_current_dir_name());
        free(cwd);
    }else{
        P7ZG_MSG("\n");
    }
    gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "");
    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
        char *filename;
        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
        gtk_entry_set_text(GTK_ENTRY(ui->archiveEty), filename);
        ui->target = gtk_entry_get_text(GTK_ENTRY(ui->archiveEty));
        g_free(filename);
    }
    gtk_widget_destroy (dialog);
}

static int CUiGetFormat(P7zgCUi* ui)
{
    int aId = gtk_combo_box_get_active(GTK_COMBO_BOX(ui->formatCbt));
    if(aId < 0){
        ui->format = -1;
    }else{
        ui->format = aId;
    }
    return 0;
}

static void formatCbtOnChange(GtkWidget* widget, void* data)
{
#define ui ((P7zgCUi*)data)
    switch(gtk_combo_box_get_active(GTK_COMBO_BOX(ui->formatCbt))){
        case FORMAT_7Z_IDX:
        case FORMAT_ZIP_IDX:
            gtk_widget_set_sensitive(GTK_WIDGET(ui->passwdEty), TRUE);
            break;
        case FORMAT_TAR_BZ2_IDX:
        case FORMAT_TAR_GZ_IDX:
            gtk_widget_set_sensitive(GTK_WIDGET(ui->passwdEty), FALSE);
            break;
    }
#undef ui
}

static void levelCbtOnChange(GtkWidget* widget, void* data)
{
}

static void methodCbtOnChange(GtkWidget* widget, void* data)
{
}

static void dictSizeCbtOnChange(GtkWidget* widget, void* data)
{

}

static void wordSizeCbtOnChange(GtkWidget* widget, void* data)
{
}

static void solidBlkSizeOnChange(GtkWidget* widget, void* data)
{
}

static void cpuThreadsOnChange(GtkWidget* widget, void* data)
{
}

static int CUiGetSplitVolSize(P7zgCUi* ui)
{
    int aId = gtk_combo_box_get_active(GTK_COMBO_BOX(ui->splitVolSizeCbt));
    if(aId == -1){
        const char* sStr = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(ui->splitVolSizeCbt));
        if(!sStr || (sStr && !strlen(sStr))){
            ui->splitVolSize = -1LL;
        }else{
            ui->splitVolSize = atoll(sStr);
        }
    }else{
        switch(aId){
            case 0:
                ui->splitVolSize = 1457664LL;
                break;
            case 1:
                ui->splitVolSize = (650LL*1024LL*1024LL);
                break;
            case 2:
                ui->splitVolSize = (700LL*1024LL*1024LL);
                break;
            case 3:
                ui->splitVolSize = (4450LL*1024LL*1024LL);
                break;
            default:
                break;
        }
    }    
    return 0;
}

static void splitVolSizeCbtOnChange(GtkWidget* widget, void* data)
{
#define ui  ((P7zgCUi*)data)

#undef ui
    P7ZG_DBG("active=%d\n", gtk_combo_box_get_active(GTK_COMBO_BOX(widget)));
}

static int CUiGetPasswd(P7zgCUi* ui)
{
    ui->passwd = gtk_entry_get_text(GTK_ENTRY(ui->passwdEty));
    if(ui->passwd && strlen(ui->passwd)){
        return 0;
    }else{
        ui->passwd = NULL;
        return 0;
    }
}

static void updateModeCbtOnChange(GtkWidget* widget, void* data)
{
}

static void passEncMethodCbtOnChange(GtkWidget* widget, void* data)
{
}

static void cancelBtnOnClick(GtkWidget* widget, void* data)
{
}

static void okBtnOnClick(GtkWidget* widget, void* data)
{
}

static void Alert(GtkWidget* parent, const char* msg)
{
    GtkWidget* dialog = gtk_message_dialog_new(GTK_WINDOW(parent), GTK_DIALOG_DESTROY_WITH_PARENT,
                             GTK_MESSAGE_ERROR,
                             GTK_BUTTONS_CLOSE,
                             msg);
    gtk_dialog_run (GTK_DIALOG (dialog));
    gtk_widget_destroy (dialog);  
}

static void MainDlgOnResponsed(GtkWidget* widget, gint id, void* data)
{
#define ui  ((P7zgCUi*)data)
    P7ZG_DBG("Responsed, ID=%d\n", id);
    if(id == GTK_RESPONSE_OK){
        if(CUiGetFormat(ui)){
            Alert(ui->mainDlg, _("Wrong format!"));
            goto ERR_OUT;
        }
        if(CUiGetTarget(ui)){
            Alert(ui->mainDlg, _("Wrong target archive specified!"));
            goto ERR_OUT;
        }
        if(CUiGetSplitVolSize(ui)){
            Alert(ui->mainDlg, _("Wrong split volume size!"));
            goto ERR_OUT;
        }
        switch(ui->format){
            case FORMAT_7Z_IDX:
            case FORMAT_ZIP_IDX:
                if(CUiGetPasswd(ui)){
                    Alert(ui->mainDlg, _("Wrong password specified!"));
                    goto ERR_OUT;
                }
                break;
        }            

        //gtk_widget_hide(GTK_WIDGET(ui->mainDlg));
        switch(ui->format){
            case FORMAT_7Z_IDX:
                ui->cRet = Compress7z(ui->fileCount, ui->fileV, ui->target, 
                -1, -1, ui->splitVolSize, ui->passwd);
                break;
            case FORMAT_TAR_BZ2_IDX:
                ui->cRet = CompressTarBzip2(ui->fileCount, ui->fileV, ui->target, 
                -1, -1, ui->splitVolSize);
                break;
            case FORMAT_TAR_GZ_IDX:
                ui->cRet = CompressTarGzip(ui->fileCount, ui->fileV, ui->target, 
                -1, -1, ui->splitVolSize);
                break;
            case FORMAT_ZIP_IDX:
                ui->cRet = CompressZip(ui->fileCount, ui->fileV, ui->target, 
                -1, -1, ui->splitVolSize, ui->passwd);
                break;
        }
        if(ui->cRet){
            Alert(ui->mainDlg, _("Something went wrong during building the archive!"));
        }
    }else if(id == GTK_RESPONSE_CANCEL){
        ui->cRet = 0;
    }else if(id == GTK_RESPONSE_DELETE_EVENT){
        ui->cRet = 0;
    }else{
        ui->cRet = -1;
    }
ERR_OUT:
    return;
#undef ui
}



int P7zgCUiInit(P7zgCUi* this, GtkWidget* parent, int fileCount, const char* target, const char** files)
{
    int i;
    GtkWidget* contentWidget;
    GtkWidget* grid;
    GtkWidget* label;
    
    this->splitVolSize = -1;
    this->fileCount = fileCount;
    this->target = target;
    this->fileV= files;
    
    this->mainDlg = gtk_dialog_new_with_buttons(_("Create archive ..."), GTK_WINDOW(parent), 
                        GTK_DIALOG_MODAL,
                        _("OK"), GTK_RESPONSE_OK,
                        _("Cancel"), GTK_RESPONSE_CANCEL,
                        NULL);
    g_signal_connect(this->mainDlg, "response", G_CALLBACK(MainDlgOnResponsed), this);
    
    contentWidget = gtk_dialog_get_content_area(GTK_DIALOG(this->mainDlg));
    grid = gtk_grid_new();
    gtk_grid_set_row_spacing(GTK_GRID(grid), 9);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 9);
    gtk_widget_show(GTK_WIDGET(grid));
    gtk_container_add(GTK_CONTAINER(contentWidget), GTK_WIDGET(grid));
    
    label = gtk_label_new(_("Archive"));
    gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 0, 1, 1);
    gtk_widget_show(GTK_WIDGET(label));
    label = gtk_label_new(_("Format"));
    gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 1, 1, 1);
    gtk_widget_show(GTK_WIDGET(label));
    label = gtk_label_new(_("Split size"));
    gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 2, 1, 1);
    gtk_widget_show(GTK_WIDGET(label));
    label = gtk_label_new(_("password"));
    gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 3, 1, 1);
    gtk_widget_show(GTK_WIDGET(label));
    
    this->archiveEty = gtk_entry_new();
    gtk_widget_show(GTK_WIDGET(this->archiveEty));
    gtk_entry_set_text(GTK_ENTRY(this->archiveEty), _(this->target));
    gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(this->archiveEty), 1, 0, 1, 1);
    
    this->archiveBrowsBtn = gtk_button_new_with_label(_("..."));
    g_signal_connect(this->archiveBrowsBtn, "clicked", G_CALLBACK(archiveBrowsBtnOnClick), this);
    gtk_widget_show(GTK_WIDGET(this->archiveBrowsBtn));
    gtk_grid_attach(GTK_GRID(grid),  GTK_WIDGET(this->archiveBrowsBtn), 2, 0, 1, 1);
    
    this->formatCbt = gtk_combo_box_text_new();
    gtk_widget_show(GTK_WIDGET(this->formatCbt));
    for(i=0; i<CF_ARRAY_SIZE(FormatNames); i++){
        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(this->formatCbt), FormatNames[i]);
    }
    g_signal_connect(this->formatCbt, "changed", G_CALLBACK(formatCbtOnChange), this);
    gtk_grid_attach(GTK_GRID(grid),  GTK_WIDGET(this->formatCbt), 1, 1, 2, 1);
    
    this->splitVolSizeCbt = gtk_combo_box_text_new_with_entry();
    gtk_widget_show(GTK_WIDGET(this->splitVolSizeCbt));
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(this->splitVolSizeCbt), _("1457664 - 3.5\" floppy"));
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(this->splitVolSizeCbt), _("650M - CD"));
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(this->splitVolSizeCbt), _("700M - CD"));
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(this->splitVolSizeCbt), _("4480M - DVD"));
    g_signal_connect(this->splitVolSizeCbt, "changed", G_CALLBACK(splitVolSizeCbtOnChange), this);
    gtk_grid_attach(GTK_GRID(grid),  GTK_WIDGET(this->splitVolSizeCbt), 1, 2, 2, 1);
    
    this->passwdEty = gtk_entry_new();
    gtk_widget_show(GTK_WIDGET(this->passwdEty));
    gtk_entry_set_text(GTK_ENTRY(this->passwdEty), "");
    gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(this->passwdEty), 1, 3, 2, 1);
    
/*
    this->archiveEty = (GtkEntry*)gtk_builder_get_object(builder, "archiveEty");
    
    this->archiveBrowsBtn = (GtkButton*)gtk_builder_get_object(builder, "archiveBrowsBtn");
    g_signal_connect(this->archiveBrowsBtn, "clicked", G_CALLBACK(archiveBrowsBtnOnClick), this);
    

    
    this->levelCbt = (GtkComboBoxText*)gtk_builder_get_object(builder, "levelCbt");
    g_signal_connect(this->levelCbt, "changed", G_CALLBACK(levelCbtOnChange), this);  
    
    this->methodCbt = (GtkComboBoxText*)gtk_builder_get_object(builder, "methodCbt");
    g_signal_connect(this->methodCbt, "changed", G_CALLBACK(methodCbtOnChange), this); 
    
    this->dictSizeCbt = (GtkComboBoxText*)gtk_builder_get_object(builder, "dictSizeCbt");
    g_signal_connect(this->dictSizeCbt, "changed", G_CALLBACK(dictSizeCbtOnChange), this);
    
    this->wordSizeCbt = (GtkComboBoxText*)gtk_builder_get_object(builder, "wordSizeCbt");
    g_signal_connect(this->wordSizeCbt, "changed", G_CALLBACK(wordSizeCbtOnChange), this);
    
    this->solidBlkSizeCbt = (GtkComboBoxText*)gtk_builder_get_object(builder, "solidBlkSizeCbt");
    g_signal_connect(this->solidBlkSizeCbt, "changed", G_CALLBACK(solidBlkSizeOnChange), this);
    
    this->cpuThreadsCbt = (GtkComboBoxText*)gtk_builder_get_object(builder, "cpuThreadsCbt");
    g_signal_connect(this->cpuThreadsCbt, "changed", G_CALLBACK(cpuThreadsOnChange), this);
    

    
    this->updateModeCbt = (GtkComboBoxText*)gtk_builder_get_object(builder, "updateModeCbt");
    g_signal_connect(this->updateModeCbt, "changed", G_CALLBACK(updateModeCbtOnChange), this);
    
    
    this->passwdCheckEty = (GtkEntry*)gtk_builder_get_object(builder, "passwdCheckEty");
    this->passEncMethodCbt = (GtkComboBoxText*)gtk_builder_get_object(builder, "passEncMethodCbt");
    g_signal_connect(this->passEncMethodCbt, "changed", G_CALLBACK(passEncMethodCbtOnChange), this);
    
    this->encFilenamesCbtn = (GtkCheckButton*)gtk_builder_get_object(builder, "encFilenamesCkb");
    
    this->cancelBtn = (GtkButton*)gtk_builder_get_object(builder, "cancelBtn");
    g_signal_connect(this->cancelBtn, "clicked", G_CALLBACK(cancelBtnOnClick), this);
    
    this->okBtn = (GtkButton*)gtk_builder_get_object(builder, "okBtn");
    g_signal_connect(this->okBtn, "clicked", G_CALLBACK(okBtnOnClick), this);    
    
    g_object_unref(builder);
*/
    return 0;
ERR_OUT:
    return -1;    
}

int P7zgCUiRun(P7zgCUi* this)
{
    gtk_widget_show(GTK_WIDGET(this->mainDlg));
    gtk_dialog_run(GTK_DIALOG(this->mainDlg));
    return this->cRet;
}

int P7zgCUiExit(P7zgCUi* this)
{
    gtk_widget_destroy(this->mainDlg);
    return 0;
}
